
package client.dm;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class windowTablero extends objTablero implements MouseListener, MouseMotionListener {
    
    private final int refreshRate = 5;
    
    private Image[][] trenes;  // tren del usuario
    private List<Image> fichasUsuario1; // fichas a mostrar del usuario
    
    private Image fichaInicial1; // ficha iniciald el juego
    private List<Integer[]> fichasUsuarioTuplas; // tuplas fichas a mostrar del usuario
    
    private Integer[] fichaInicialT; // tupla
    private String[] Nombres; // nombres
    
    private int trenCliente;
    private int numJugador;
    
    private Escucha hilo;
    
    private String[] strPlayerName = {"","","","","","","",""};
    private String strStatusMsg = "";
    private objCellMatriz cellMatrix = new objCellMatriz(); // marcadores de trenes
    private int startRow = 0, startColumn = 0;
    private int currentX = 0, currentY = 0, refreshCounter = 0, pieceBeingDragged =  0, desRow = 0, desColumn = 0;
    private int marca0=0, marca1=0, marca2=0, marca3=0, marca4=0, marca5=0, marca6=0, marca7=0, marca8=0;
    private boolean firstTime = true, hasWon = false, isDragging = false, dibujar = false, again = false, ccolor = false;
    
    public windowTablero() {
        
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        
        this.trenes = new Image[9][6];
        this.Nombres = new String [9];
        objCreateAppletImage createImage = new objCreateAppletImage();
        for(int fila = 0; fila < 9; fila ++)
        {
            for(int colum = 0; colum < 6; colum ++)
            {
                trenes[fila][colum] =  createImage.getImage(this, "resources/nada.gif", 5000);
            }
            if (fila == 0)
                Nombres[fila] = "Tren";
            else
                Nombres[fila] = "";
        }
        this.fichasUsuario1 = new ArrayList<Image>();
        this.fichaInicial1 = null;
        this.fichasUsuarioTuplas = new ArrayList<Integer[]>();
        this.fichaInicialT = new Integer [2];
        this.numJugador = 0;
        this.trenCliente = 0;  
    }

    public void setFirstTime(boolean firstTime) {
        this.firstTime = firstTime;
    }

    public void setHasWon(boolean hasWon) {
        this.hasWon = hasWon;
    }

    public Image getFichaInicial1() {
        return fichaInicial1;
    }

    public Integer[] getFichaInicialT() {
        return fichaInicialT;
    }

    public List<Image> getFichasUsuario1() {
        return fichasUsuario1;
    }

    public void setFichaInicial1(Image fichaInicial1) {
        this.fichaInicial1 = fichaInicial1;
    }

    public void setFichaInicialT(Integer[] fichaInicialT) {
        this.fichaInicialT = fichaInicialT;
    }

    public Escucha getHilo() {
        return hilo;
    }

    public List<Integer[]> getFichasUsuarioTuplas() {
        return fichasUsuarioTuplas;
    }

    public void setFichasUsuarioTuplas(List<Integer[]> fichasUsuarioTuplas) {
        this.fichasUsuarioTuplas = fichasUsuarioTuplas;
    }

    public String[] getNombres() {
        return Nombres;
    }    

    public int getNumJugador() {
        return numJugador;
    }

    public void setNumJugador(Integer num) {
        numJugador = num;
    }
    
    public void setStrStatusMsg(String strStatusMsg) {
        this.strStatusMsg = strStatusMsg;
    }
    
    public void setAgain(boolean again) {
        this.again = again;
    }

    public void setHilo(Escucha hilo) {
        this.hilo = hilo;
    }
    
    //Siver para cambiar los mensajes que vez en el tablero
    public String getPlayerMsg() {
        
        if (hasWon) {
            return "Felicitaciones " + strPlayerName[0] + ", tu eres el ganadaror!";
        } else if (firstTime) {
            return "" + strPlayerName[0] + " Nuevo juego";
        } else if (again) {
            return "" + strPlayerName[0] + ", debes cobrar el doble!";
        }
        else {
            return "" + strPlayerName[0] + " Elige una ficha para un tren";
        }
        
    }
    
    //Comiezan el juego de nuevo
    private void resetBoard() {
        
        hasWon = false;
        strStatusMsg = getPlayerMsg();
        cellMatrix.resetMatrix();        
        repaint();
        
    }
    
    public void setupImages(List<Image> fichasUsuario,Image fichaInicial, List<Integer[]> tuplasU, Integer[] tuplaIn ) {
        fichasUsuario1 = fichasUsuario;
        fichaInicial1 = fichaInicial;
        fichasUsuarioTuplas = tuplasU;
        fichaInicialT = tuplaIn;
        resetBoard();
        
    }
    
    //Estabke los nombres a los jugadores
    
    public void setNames(String strPlayer1Name, int posicion) {
        
        strPlayerName[posicion] = strPlayer1Name;
        strStatusMsg = getPlayerMsg();
        repaint();
        
    }
    
    protected void drawExtra(Graphics g) {
       
       if(dibujar)
       {
           g.drawImage(fichaInicial1, 580, 0, 70, 30, Color.blue, this);
           int countIm = 0;

           for(int fila = 10; fila < 13; fila ++)
           {
               for(int colum = 0; colum < 6; colum ++)
               {
                   try 
                   {
                       if(fichasUsuario1.size()>countIm)
                       {                       
                           g.drawImage(fichasUsuario1.get(countIm), ((colum * 100) + 5), ((fila * 50) + 50), 70, 30, this);
                           countIm ++;
                       }                   
                   } catch (ArrayIndexOutOfBoundsException e) {
                   }
               }
           }
           for(int fila = 0; fila < 9; fila ++)
           {
               for(int colum = 0; colum < 6; colum ++)
               {
                   try 
                   {
                       if(!trenes[fila][colum].equals(null))
                       {                       
                           g.drawImage(trenes[fila][colum], ((colum * 100)+5), ((fila * 50)+50), 70, 30, this);
                       }                   
                   } catch (ArrayIndexOutOfBoundsException e) {
                   }
               }
               if(ccolor)
               {
                   if(cellMatrix.getPlayerMatrix()[fila]==1)
                   {
                       g.setColor(Color.MAGENTA);
                       g.drawRect(fila, ((fila * 50)+40),50,30);
                       g.setColor(Color.BLACK);
                   }
               }
               g.drawString(Nombres[fila], fila, ((fila * 50)+40));
       }
       if (isDragging) {
            g.drawImage(fichasUsuario1.get(pieceBeingDragged), (currentX - 25), (currentY - 25),70,30, this);
        }
        g.setColor(new Color(0,0,0));
        g.drawString(strStatusMsg, 50, 520);

        vecPaintInstructions.clear();
       }
       else
       {
           if(hasWon)
           {
                g.setColor(new Color(0,0,0));
                g.drawString(getPlayerMsg(), 50, 520);

                vecPaintInstructions.clear();
           }
       }
    }

    public void setNombreJugador(String strPlayerName) {
        this.strPlayerName[0] = strPlayerName;
    }
    
    public String getNombreJugador() {
        return this.strPlayerName[0];
    }
    //Nuevo juegi
    public void newGame() {
        firstTime = false;
        dibujar = true;
        resetBoard();
    }
    
    public void unsucessfullDrag() {
        
        cellMatrix.setPieceCell(startRow, startColumn, pieceBeingDragged); 
    }
    
    private void updatePaintInstructions() {
        
        currentInstruction = new objPaintInstruction(startRow, startColumn, 1);
        vecPaintInstructions.addElement(currentInstruction);
        
        currentInstruction = new objPaintInstruction(desRow, desColumn);
        vecPaintInstructions.addElement(currentInstruction);
        
    }
    
    public void paint(Graphics g)
    {
        drawExtra(g);
    }
    
    //Valida los movimientos
    
    private void checkTren() { // Y X
        boolean legalMove = false;                
        if (cellMatrix.getTrenAb(desRow) == 0) 
        {
            strStatusMsg = "No puedes mover";
        } else {
            legalMove = true;
            if(desRow == trenCliente && desColumn == 0)
            { 
                legalMove = false;
                Integer[] v1 = fichasUsuarioTuplas.get(pieceBeingDragged);
                if (v1[1] == fichaInicialT[1])
                {
                    legalMove = true;    
                }
                if (v1[0] == fichaInicialT[1])
                {
                    legalMove = true;    
                }
            }
        }
        
        if (legalMove) 
        {
            int marca = getMarca(desRow);
            System.out.println("USURAIO: marca"+marca);
            if((desColumn==marca) || (marca == 0))//ubicar la ficha en la posicion correcta de la fila
            {
                if(fichasUsuario1.size()==1)
                {
                    // enviar al servidor para verficar movimiento, ultima ficha finishline_#_[4,6]
                    //Integer[] v1 = (Integer[]) trenesTuplas.get(desRow+","+desColumn);
                    Integer[] v1 = fichasUsuarioTuplas.get(pieceBeingDragged);
                    hilo.msj("finishline_"+desRow+"_["+v1[0]+","+v1[1]+"]");
                }
                else
                {// enviar al servidor para verficar move_#_[4,6]
                    //Integer[] v1 = (Integer[]) trenesTuplas.get(desRow+","+desColumn);
                    Integer[] v1 = fichasUsuarioTuplas.get(pieceBeingDragged);
                    hilo.msj("move_"+desRow+"_["+v1[0]+","+v1[1]+"]");
                }
            }
             else
            {
                strStatusMsg = "Movimiento errado";
                unsucessfullDrag(); 
            }
        } else {
            
            strStatusMsg = "Movimiento errado";
            unsucessfullDrag();            
        }
        
    }
    
    
    /*Sirve para poder controloar los eventos del mouse, esto es lo que se llama el famoso
     drag and drop
     */
    
    public void mouseClicked(MouseEvent e) {
    }
    
    public void mouseEntered(MouseEvent e) {
    }
    
    public void mouseExited(MouseEvent e) {
        mouseReleased(e);
    }
    
    public void mousePressed(MouseEvent e) {
        if (!hasWon && !firstTime) {
            
            int x = e.getX();
            int y = e.getY();
            
            if ((x > 0 && x < 700) && (y > 400 && y < 700)) {
                
                startRow = encontrarFichaY(y);
                startColumn = encontrarFichaX(x);
                                
                if(startRow == 10)
                {
                    pieceBeingDragged = startColumn; 
                }
                else if(startRow == 11)
                {
                     pieceBeingDragged = startColumn+6; 
                }
                else if(startRow == 12)
                {
                     pieceBeingDragged = startColumn+12; 
                }
                cellMatrix.setTrenAb(startRow, 0);
                isDragging = true;
                    
            }
            
        }
        
    }
    
    public void mouseReleased(MouseEvent e) {
        
        if (isDragging) {
            
            isDragging = false;
            if(currentY == 0 && currentX == 0)
            {}
            else
            {
                System.out.println("actual X Y  "+currentY+":"+currentX);
                desRow = encontrarFichaY(currentY);
                System.out.println("YYYYYYYYYYYYYYYY: "+desRow);
                desColumn = encontrarFichaX(currentX);
                System.out.println("XXXXXXXXXXXXXx: "+desColumn);
                checkTren();
                repaint();
            }
        }        
    }
    
    @Override
    public void mouseDragged(MouseEvent e) {
        
        if (isDragging) {
            
            int x = e.getX();
            int y = e.getY();
            
            if ((x > 0 && x < 700) && (y > 0 && y < 500)) {
                
                if (refreshCounter >= refreshRate) {
                    
                    currentX = x;
                    currentY = y;
                    refreshCounter = 0;
                    desRow = encontrarFichaY(currentY);
                    desColumn = encontrarFichaX(currentX);
                    
                    updatePaintInstructions();
                    repaint();
                    
                } else {
                    refreshCounter++;
                }
                
            }
            
        }
        
    }
    
    public void mouseMoved(MouseEvent e) {
    }
    
    public void gotFocus() {
        repaint();
    }

    private int getMarca(int desColumn) {
        int marca = 0;
            switch(desColumn)
            {
                case 0:marca = marca0;
                       break;
                case 1:marca = marca1;
                       break;
                case 2:marca = marca2;
                       break;
                case 3:marca = marca3;
                       break;
                case 4:marca = marca4;
                       break;
                case 5:marca = marca5;
                       break;
                case 6:marca = marca6;
                       break;
                case 7:marca = marca7;
                       break;
                case 8:marca = marca8;
                       break;
            }
            return marca;
    }

    private void setMarca(int valor, int marca) {
        switch(marca)
            {
                case 0:marca0 = 0;
                       break;
                case 1:marca1 = valor;
                       break;
                case 2:marca2 = valor;
                       break;
                case 3:marca3 = valor;
                       break;
                case 4:marca4 = valor;
                       break;
                case 5:marca5 = valor;
                       break;
                case 6:marca6 = valor;
                       break;
                case 7:marca7 = valor;
                       break;
                case 8:marca8 = valor;
                       break;
            }
    }
    
    public void moverFicha()
    { 
        int y = desColumn;
        if(desColumn == 5)
        {          
            for (int i = 0; i < 4; i ++)
            {
                trenes[desRow][i] = trenes[desRow][i+1];
            } 
            y = desColumn-1;
        }
        trenes[desRow][y] = fichasUsuario1.get(pieceBeingDragged);
        fichasUsuario1.remove(pieceBeingDragged);
        fichasUsuarioTuplas.remove(pieceBeingDragged);
        setMarca(y+1,desRow );
        if(fichasUsuario1.size()==0)
        {
            hasWon = true;
            dibujar = false;
        }
        repaint();
    }

    public void pasar() 
    {
        hilo.msj("pass_"+numJugador);
    }

    public void pedirFicha() {
        hilo.msj("ask_"+numJugador);
    }

    public void terminar(String quien) {
        this.setEnabled(false);
        System.exit(0);
        JFrame frame = new JFrame("Dominó Mexicano");
        JOptionPane.showMessageDialog(frame,"Ha terminado el juego, "+quien+" es el ganador!");
    }

    void setMarcadorTren(int secCommand, int i) {
        cellMatrix.getPlayerMatrix()[secCommand] = 1;
    }

    void cambiarColor(Integer fila) {
        ccolor = true;
        repaint();
    }

    void moverFichaJugador(int fila, Image fichaI) {
        
        int y = getMarca(fila);
        if(y == 5)
        {          
            for (int x = 0; x < 4; x ++)
            {
                trenes[fila][x] = trenes[fila][x+1];
            } 
            y = y-1;
        }
        trenes[fila][y] = fichaI;
        setMarca(y+1,fila);        
        repaint();
    }
}